home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / snip1292.zip / SETVOL.C < prev    next >
C/C++ Source or Header  |  1992-12-26  |  4KB  |  187 lines

  1. /*
  2. **  SETVOL.C - set, change, or kill a disk volume label
  3. **
  4. **  public domain demo by Bob Stout
  5. **  DOS 5 enhancements suggested by Keith Beedle
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <dos.h>
  12. #include <io.h>
  13.  
  14. #if defined(__TURBOC__)
  15.  #pragma option -a-
  16.  #include <dir.h>
  17.  #define _dos_findfirst(f,a,b) findfirst(f,b,a)
  18.  #define _dos_findnext(b) findnext(b)
  19.  #define find_t ffblk
  20.  #define _A_VOLID FA_LABEL
  21.  #define attrib ff_attrib
  22.  #define name ff_name
  23.  #define size ff_size
  24.  #define wr_time ff_time
  25.  #define wr_date ff_date
  26.  #define dos_creat _creat
  27. #else
  28.  #include <direct.h>
  29.  #if defined(__ZTC__)
  30.   #pragma ZTC align 1
  31.  #else /* MSC/QC/WATCOM/METAWARE */
  32.   #pragma pack(1)
  33.   int dos_creat(const char *fname, unsigned attrib)
  34.   {
  35.         int fd;
  36.  
  37.         if (_dos_creat(fname, attrib, &fd))
  38.                 return -1;
  39.         else    return fd;
  40.   }
  41.  #endif
  42.  struct fcb {
  43.          char   fcb_drive;
  44.          char   fcb_name[8];
  45.          char   fcb_ext[3];
  46.          short  fcb_curblk;
  47.          short  fcb_recsize;
  48.          long   fcb_filsize;
  49.          short  fcb_date;
  50.          char   fcb_resv[10];
  51.          char   fcb_currec;
  52.          long   fcb_random;
  53.  };
  54.  
  55.  struct xfcb {
  56.          char           xfcb_flag;
  57.          char           xfcb_resv[5];
  58.          char           xfcb_attr;
  59.          struct fcb     xfcb_fcb;
  60.  };
  61. #endif
  62.  
  63. #include "dos5boot.h"   /* SNIPPETS file with DOS 5 boot record structure  */
  64.  
  65. /*
  66. **  NOTE: The following use functions in two other SNIPPETS files,
  67. **        ABSDISK.ASM & ABSDISKC.C
  68. */
  69.  
  70. int AbsDiskRead(unsigned short, size_t, size_t, void *);
  71. int AbsDiskWrite(unsigned short, size_t, size_t, void *);
  72.  
  73. /*
  74. **  Erase an existing volume label
  75. */
  76.  
  77. void vol_kill(char *fname)
  78. {
  79.       union REGS regs;
  80.       struct SREGS sregs;
  81.       struct xfcb buf;
  82.  
  83.       /* Parse the filename into an FCB               */
  84.  
  85.       segread(&sregs);
  86.       regs.h.ah = 0x29;
  87.       regs.h.al = 0;
  88.       regs.x.si = (unsigned)fname;
  89.       regs.x.di = (unsigned)&buf.xfcb_fcb;
  90.       sregs.es  = sregs.ds;
  91.       intdosx(®s, ®s, &sregs);
  92.  
  93.       /* Volume labels require extended FCB's         */
  94.  
  95.       buf.xfcb_flag = 0xff;
  96.       buf.xfcb_attr = _A_VOLID;
  97.  
  98.       /* Delete the old label                         */
  99.  
  100.       regs.h.ah = 0x13;
  101.       regs.x.dx = (unsigned)&buf;
  102.       intdos(®s, ®s);
  103. }
  104.  
  105. /*
  106. **  Create a new volume label
  107. */
  108.  
  109. void setvol(char *label)
  110. {
  111.       int fd;
  112.       char new_label[13];     /* name + ext + '.' + NUL       */
  113.       struct find_t finfo;
  114.       union REGS regs;
  115.  
  116.       /*
  117.       **  Change to root directory.
  118.       **
  119.       **  NOTE: To make this more robust, use pushdir() & popdir(),
  120.       **  also from SNIPPETS.
  121.       */
  122.       
  123.       chdir("\\");
  124.  
  125.       /* If drive is already labeled, remove it               */
  126.  
  127.       if (0 == _dos_findfirst("*.*", _A_VOLID, &finfo)) do
  128.       {
  129.             if (_A_VOLID & finfo.attrib)
  130.                   break;
  131.       } while (0 == _dos_findnext(&finfo));
  132.  
  133.       if (_A_VOLID & finfo.attrib)
  134.             vol_kill(finfo.name);
  135.  
  136.       strcpy(new_label, label);
  137.       if (8 < strlen(label))
  138.       {
  139.             new_label[8] = '.';
  140.             strcpy(&new_label[9], &label[8]);
  141.       }
  142.  
  143.       fd = dos_creat(new_label, _A_VOLID);/* Create new label */
  144.       close(fd);
  145.  
  146.       /*
  147.       **  For DOS 5.0 replace the boot record too.
  148.       */
  149.  
  150.       if(_osmajor > 3)
  151.       {
  152.             int index;
  153.             B_REC boot_record;
  154.  
  155.             AbsDiskRead(0, 1, 0, &boot_record);
  156.             if(0 == strcmp(boot_record.bsOemName, "MSDOS5.0"))
  157.             {
  158.                   index = 0;
  159.                   while (NULL != label[index])
  160.                   {
  161.                         boot_record.bsVolumeLabel[index] = label[index];
  162.                         index++;
  163.                   }
  164.                   for(index; index < 11; index++)
  165.                         boot_record.bsVolumeLabel[index] = 0x20;
  166.                   AbsDiskWrite(0, 1, 0, &boot_record);
  167.             }
  168.       }
  169.       /*
  170.       **  NOTE: If you used pushdir() above, use popdir() here.
  171.       */
  172. }
  173.  
  174. #ifdef TEST
  175.  
  176. void main(int argc, char *argv[])
  177. {
  178.       if (2 > argc)
  179.       {
  180.             puts("\aUsage: SETVOL new_name");
  181.             abort();
  182.       }
  183.       setvol(argv[1]);
  184. }
  185.  
  186. #endif
  187.